#pragma once

#include "loirey_GLOBAL.h"
#include "loirey_MyMath.h"
#include "loirey_BasicStructure.h"

namespace loirey
{
	class CxmlTreeNode
	{
	public:
		int NotationID;
		const string* pNotationName;
		string strContent;

		CxmlTreeNode* pParent;
		CxmlTreeNode* pFirstChild;
		CxmlTreeNode* pLastChild;
		CxmlTreeNode* pPreviousBrother;
		CxmlTreeNode* pNextBrother;

	public:
		CxmlTreeNode();
		~CxmlTreeNode();

		void OutputNodeToStream(ostream& outStream, int StepInto = 0);
		void OutputTreeToStream(ostream& outStream, int StepInto = 0);

		CxmlTreeNode* GetNewChild();
		CxmlTreeNode* GetNextNode_PreorderTraversal();
		CxmlTreeNode* GetNextNode_PostorderTraversal();

		CxmlTreeNode* GetNextChildWithNotation(int NotationID, CxmlTreeNode* pCurrentChild = NULL);
	};

	class CxmlTree
	{
	protected:
		static const int BUF_SIZE = 1024*1024;
		static const char* IGNORING_CHARS;
		static const string STR_ROOT;
	protected:
		int _head, _tail;
		char* _buf;
		FILE* FIN;
		bool fEOF;
	protected:
		char _CurrentChar;
	public:
		CSimpleDictionary<string> NotationDict;
		bool fIsNotationCaseSensitive;
		bool fIsContentCaseSensitive;
	public:
		CxmlTreeNode* Root;

	protected:
		char _NextChar();
		char _NextNonIgnoringChar();
		int _NextToken(string& DstString);
	private:
		void __BuildTree(bool fIsNotationCaseSensitive, bool fIsContentCaseSensitive);
	public:
		void myRelease();
		CxmlTree();
		~CxmlTree();

		int GetNotationID(string strNotationName);

		void myInit(string strFN_XML);
		void myInit(string strFN_XML, bool fIsNotationCaseSensitive, bool fIsContentCaseSensitive);
		void OutputToStream(ostream& outStream, int StepInto = 0);

		CxmlTreeNode* GetFirstNode_PreorderTraversal();
		CxmlTreeNode* GetFirstNode_PostorderTraversal();
	};
}

